package boundarys;

import java.awt.Font;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import ccrm.BoundryControl;
import controllers.AssociateProductController;
import controllers.DeleteProductController;
import controllers.ManageCategoriesController;
import controllers.ManageTypesController;
import entitys.Category;
import entitys.Product;
import entitys.ProductInType;
import entitys.Reply;
import entitys.Type;
import enums.Command;
import enums.Result;

public class AssociateProductGUI extends AbstractGUI{

	/**
	 * Associate products frame
	 */
	private JFrame frmCcrmAssociateProduct;
	/**
	 * Lists for products, types, categories, and associations(trio)
	 */
	private List productList;			
	private List typeList;
	private List categoryList;
	private List trioList;
	/**
	 * Labels
	 */
	private JLabel productLabel;
	private JLabel typeLabel;
	private JLabel categoryLabel;
	private JLabel trioLabel;
	/**
	 * Buttons
	 */
	private JButton RefreshBtn;
	private JButton AssociateBtn;
	private JButton DeleteBtn;
	private JButton DoneBtn;
	private JButton ConfirmBtn;
	
	/**
	 * Constructor
	 */
	public AssociateProductGUI() {
		initialize();
		initGUI(frmCcrmAssociateProduct);
		frmCcrmAssociateProduct.getContentPane().setLayout(null);
		
		productList = new List();
		productList.setMultipleSelections(false);
		productList.setBounds(20, 75, 198, 282);
		frmCcrmAssociateProduct.getContentPane().add(productList);
		/**
		 * sends the server a request to get the products list from the database
		 */
		DeleteProductController.getProducts();
		
		typeList = new List();
		typeList.setMultipleSelections(false);
		typeList.setBounds(240, 75, 198, 282);
		frmCcrmAssociateProduct.getContentPane().add(typeList);
		/**
		 * sends the server a request to get the product types list from the database
		 */
		ManageTypesController.getProductTypes();
		
		categoryList = new List();
		categoryList.setBounds(464, 75, 198, 282);
		frmCcrmAssociateProduct.getContentPane().add(categoryList);
		/**
		 * sends the server a request to get the product categories list from the database
		 */
		ManageCategoriesController.getProductCategories();
		/**
		 * sends the server a request to get the associations list from the database
		 */
		AssociateProductController.getTrio();
		
		productLabel = new JLabel("Select product to associate:");
		productLabel.setFont(new Font("Tahoma", Font.BOLD, 11));
		productLabel.setBounds(20, 44, 198, 25);
		frmCcrmAssociateProduct.getContentPane().add(productLabel);
		
		typeLabel = new JLabel("Select type:");
		typeLabel.setFont(new Font("Tahoma", Font.BOLD, 11));
		typeLabel.setBounds(298, 44, 100, 25);
		frmCcrmAssociateProduct.getContentPane().add(typeLabel);
		
		categoryLabel = new JLabel("Select category:");
		categoryLabel.setFont(new Font("Tahoma", Font.BOLD, 11));
		categoryLabel.setBounds(515, 44, 120, 25);
		frmCcrmAssociateProduct.getContentPane().add(categoryLabel);
		
		/**
		 * Action Listener for Associate Button
		 * Checks that a product,type and category were selected and if such association does not exists it associates
		 * this combination and adds to the association list and updates the database
		 */
		AssociateBtn = new JButton("Associate");
		AssociateBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(BoundryControl.GUIArr.size()==getIndex()+1)//last on GUI's list
				{
					String p,t,c;
					int pid,tid,cid;
					if(!(productList.getSelectedItem()!=null && typeList.getSelectedItem()!=null && categoryList.getSelectedItem()!=null))
						JOptionPane.showMessageDialog(frmCcrmAssociateProduct, "Must select product,type and category", "CCRM Associate Product", JOptionPane.ERROR_MESSAGE);
					else {
							p = (String)productList.getSelectedItem();
							t = (String)typeList.getSelectedItem();
							c = (String)categoryList.getSelectedItem();
							pid = Integer.parseInt(p.substring(1,p.indexOf(" ")).trim());
							tid = Integer.parseInt(t.substring(1,t.indexOf(" ")).trim());
							cid = Integer.parseInt(c.substring(1,c.indexOf(" ")).trim());

								AssociateProductController.associateProduct(pid, tid, cid);
					}
				}
			}});

		AssociateBtn.setBounds(931, 75, 109, 58);
		frmCcrmAssociateProduct.getContentPane().add(AssociateBtn);
		
		/**
		 * Action Listener for Refresh Button
		 * Gets updated data from database and updates the lists in the frame accodringly
		 */
		RefreshBtn = new JButton("Refresh");
		RefreshBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(BoundryControl.GUIArr.size()==getIndex()+1)//last on GUI's list
				{
					DeleteProductController.getProducts();
					ManageTypesController.getProductTypes();
					ManageCategoriesController.getProductCategories();
					AssociateProductController.getTrio();
					
				}
			}
		});
		RefreshBtn.setBounds(931, 213, 109, 58);
		frmCcrmAssociateProduct.getContentPane().add(RefreshBtn);
		
		trioLabel = new JLabel("Associations in db: ( pid - tid - cid)");
		trioLabel.setFont(new Font("Tahoma", Font.BOLD, 11));
		trioLabel.setBounds(700, 44, 210, 25);
		frmCcrmAssociateProduct.getContentPane().add(trioLabel);
		
		trioList = new List();
		trioList.setMultipleSelections(false);
		trioList.setBounds(700, 75, 198, 282);
		frmCcrmAssociateProduct.getContentPane().add(trioList);
		
		DeleteBtn = new JButton("Delete");
		/**
		 * Action Listener for Delete Button
		 * Hides all buttons and shows done and confirm buttons, and in addition disables other lists except the association list
		 */
		DeleteBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(BoundryControl.GUIArr.size()==getIndex()+1)//last on GUI's list
				{			
					productList.deselect(productList.getSelectedIndex());
					typeList.deselect(typeList.getSelectedIndex());
					categoryList.deselect(categoryList.getSelectedIndex());
				
					DeleteBtn.setVisible(false);
					AssociateBtn.setVisible(false);
					DoneBtn.setVisible(true);
					ConfirmBtn.setVisible(true);
					productList.setEnabled(false);
					typeList.setEnabled(false);
					categoryList.setEnabled(false);
				}
			}
		});
		DeleteBtn.setBounds(931, 144, 109, 58);
		frmCcrmAssociateProduct.getContentPane().add(DeleteBtn);
		
		DoneBtn = new JButton("Done");
		/**
		 * Action Listener for Done Button
		 * hides the done and confirm buttons, shows original buttons and enables all lists except the association list
		 */
		DoneBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(BoundryControl.GUIArr.size()==getIndex()+1)//last on GUI's list
				{	
					DoneBtn.setVisible(false);
					DeleteBtn.setVisible(true);
					AssociateBtn.setVisible(true);
					ConfirmBtn.setVisible(false);
					productList.setEnabled(true);
					typeList.setEnabled(true);
					categoryList.setEnabled(true);
				}
			}
		});
		DoneBtn.setBounds(931, 144, 109, 58);
		DoneBtn.setVisible(false);
		frmCcrmAssociateProduct.getContentPane().add(DoneBtn);

		ConfirmBtn = new JButton("Confirm");
		
		/**
		 * Action Listener for Confirm Button
		 * Checks if an association was selected, is yes it deletes it from the list and updates the database
		 */
		ConfirmBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(BoundryControl.GUIArr.size()==getIndex()+1)//last on GUI's list
				{
					int pid, tid, cid, indexstart, indexend;
					String association;
					
					if(trioList.getSelectedItem()==null)
						JOptionPane.showMessageDialog(frmCcrmAssociateProduct, "Must select an association", "CCRM Delete Association", JOptionPane.ERROR_MESSAGE);
					else
					{
						association = (String)trioList.getSelectedItem();
						indexend = findendtypeindex(association);
						indexstart = association.indexOf(" ");
						pid = Integer.parseInt(association.substring(1,association.indexOf(" ")).trim());
						tid = Integer.parseInt(association.substring(indexstart+4,indexend));
						cid = Integer.parseInt(association.substring(indexend+4,association.length()));
						
						AssociateProductController.deleteAssociation(pid, tid, cid);
					}
				}
			}

			/**
			 * 
			 * @param association
			 * @return the index where the type name ends
			 */
			private int findendtypeindex(String association) {
				// TODO Auto-generated method stub
				int count=0, index = 0;
				for(int i=0;i<association.length();i++)
				{
					if(association.charAt(i)==' ') count++;
					if(count==3){
						index = i;
						break;
					}
				}
				return index;
			}
		});
		ConfirmBtn.setBounds(931, 75, 109, 58);
		ConfirmBtn.setVisible(false);
		frmCcrmAssociateProduct.getContentPane().add(ConfirmBtn);
		

	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmCcrmAssociateProduct = new JFrame();
		frmCcrmAssociateProduct.getContentPane().addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				productList.deselect(productList.getSelectedIndex());
				typeList.deselect(typeList.getSelectedIndex());
				categoryList.deselect(categoryList.getSelectedIndex());
				trioList.deselect(trioList.getSelectedIndex());
			}
		 });
		frmCcrmAssociateProduct.setTitle("...Manage Product Category/Type>Associate Product");
		frmCcrmAssociateProduct.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frmCcrmAssociateProduct.setResizable(false);
		frmCcrmAssociateProduct.setBounds(100, 100, 1074, 418);
		frmCcrmAssociateProduct.setVisible(true);
	}

	@Override
	/**
	 * Reply from server
	 * Does the right action according to the command that was sent from the controller
	 */
	public void getReply(Object r) {
		// TODO Auto-generated method stub
		if(((Reply)r).command.equals(Command.GET_PRODUCTS)) //if GET_PRODUCTS reply is received
		{
			ArrayList<Product> arrp =(ArrayList<Product>) ((Reply)r).result;
			productList.removeAll();
			
			for(int i=0;i<arrp.size();i++)
			{
				productList.add(arrp.get(i).toString());
			}
		}
		else if(((Reply)r).command.equals(Command.GET_PRODUCT_TYPES)) //if GET_PRODUCTS reply is received
		{
			ArrayList<Type> arrt =(ArrayList<Type>) ((Reply)r).result;
			typeList.removeAll();
			
			for(int i=0;i<arrt.size();i++)
			{
				typeList.add(arrt.get(i).toString());
			}
		}
		
		else if(((Reply)r).command.equals(Command.GET_PRODUCT_CATEGORIES)) //if GET_PRODUCTS reply is received
		{
			ArrayList<Category> arrc =(ArrayList<Category>) ((Reply)r).result;
			categoryList.removeAll();
			
			for(int i=0;i<arrc.size();i++)
			{
				categoryList.add(arrc.get(i).toString());
			}
		}
		
		else if(((Reply)r).command.equals(Command.GET_TRIO)) //if GET_TRIO reply is received
		{
			ArrayList<ProductInType> arrtrio =(ArrayList<ProductInType>) ((Reply)r).result;
			trioList.removeAll();
			
			for(int i=0;i<arrtrio.size();i++)
			{
				trioList.add(arrtrio.get(i).toString());
			}
		}
		
		else if(((Reply)r).command.equals(Command.ASSOCIATE_PRODUCT)) //if GET_TRIO reply is received
		{
			if (((Reply)r).result.equals(Result.OK))
			{
				System.out.println("Product associated successfully!");
				JOptionPane.showMessageDialog(frmCcrmAssociateProduct, "Product associated successfully", "CCRM Associate Product", JOptionPane.INFORMATION_MESSAGE);
			}
			else if (((Reply)r).result.equals(Result.FAILED))
			{
				System.out.println("Product wasn't associated!");
				JOptionPane.showMessageDialog(frmCcrmAssociateProduct, "Unable to associated existing association", "CCRM Associate Product", JOptionPane.ERROR_MESSAGE);
			}
			AssociateProductController.getTrio();
		}
		
		else if(((Reply)r).command.equals(Command.DELETE_ASSOCIATION)) //if GET_TRIO reply is received
		{
			if (((Reply)r).result.equals(Result.OK))
			{
				System.out.println("Association deleted successfully!");
				JOptionPane.showMessageDialog(frmCcrmAssociateProduct, "Association deleted successfully", "CCRM Delete Association", JOptionPane.INFORMATION_MESSAGE);
			}
			AssociateProductController.getTrio();
		}
		
	}
}
